package com.xbongbong.workorder.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkListPojo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.OwnerAndCoUserHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.CustomerUserPojo;
import com.xbongbong.paas.pojo.DataDetailPojo;
import com.xbongbong.paas.pojo.DetailTabPojo;
import com.xbongbong.paas.pojo.DetailTitlePojo;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.HandelDetailPojo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.WorkFlowPojo;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.service.DetailTabConfigService;
import com.xbongbong.paas.service.LinkListService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.RoleSimpleVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.TitleUtil;
import com.xbongbong.parent.abstracts.AbstractBusinessDetailTopInfoService;
import com.xbongbong.parent.parse.data.FormDataDetailAnalysisDataHelp;
import com.xbongbong.pro.appdetail.pojo.MobileDetailManagerBlockPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailMoneyItemPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailScriptPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailSpecialInfoPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailStatusBlockPojo;
import com.xbongbong.pro.appdetail.pojo.MobileDetailStatusPojo;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.LocationConstant;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.DeleteProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.enums.permission.enums.UpdateProPermissionAliasEnum;
import com.xbongbong.pro.form.pojo.TopPermissionsPoJo;
import com.xbongbong.pro.formdata.pojo.dto.FormDataDetailDTO;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formdata.pojo.vo.MobileFormCommonDetailVO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.permission.pojo.dto.VerifyViewPermissionDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFlowNodeEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFlowUserEntity;
import com.xbongbong.saas.domain.entity.WorkOrderStageEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.BusinessDetailButtonEnum;
import com.xbongbong.saas.enums.BusinessDetailTabEnum;
import com.xbongbong.saas.enums.MobileDetailBottomOperationEnum;
import com.xbongbong.saas.enums.SaasButtonEnum;
import com.xbongbong.saas.enums.WorkFlowEnum;
import com.xbongbong.saas.enums.WorkOrderFlowNodeTypeEnum;
import com.xbongbong.saas.enums.WorkOrderNodeStatusEnum;
import com.xbongbong.saas.enums.WorkOrderStageRobTypeEnum;
import com.xbongbong.saas.enums.WorkOrderStageRuleEnum;
import com.xbongbong.saas.enums.WorkOrderStatusEnum;
import com.xbongbong.saas.enums.WorkOrderTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.dictionary.WorkOrderShipStatusEnum;
import com.xbongbong.saas.help.LabelHelp;
import com.xbongbong.saas.model.WorkOrderCcModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFlowNodeModel;
import com.xbongbong.saas.model.WorkOrderFlowUserModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderModel;
import com.xbongbong.saas.model.WorkOrderStageModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.RoleEnum;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.util.NameUtil;
import com.xbongbong.util.SummaryUtil;
import com.xbongbong.workorder.explain.WorkOrderFormDataFormExplainHandleName;
import com.xbongbong.workorder.service.WorkOrderBasicService;
import com.xbongbong.workorder.service.WorkOrderFlowUserService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author 吴峰
 * @date 2022/02/14 9:48
 */
@Service("wordOrderDetailTopInfoServiceImpl")
public class WorkOrderDetailTopInfoServiceImpl extends AbstractBusinessDetailTopInfoService<WorkOrderFormEntityExt, WorkOrderEntity>  {
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkOrderModel workOrderModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private WorkOrderFormDataFormExplainHandleName workOrderFormDataFormExplainHandleName;
    @Resource
    private OwnerAndCoUserHelp ownerAndCoUserHelp;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private UserModel userModel;
    @Resource
    private WorkOrderFlowUserService workOrderFlowUserService;
    @Resource
    private WorkOrderFlowNodeModel workOrderFlowNodeModel;
    @Resource
    private WorkOrderStageModel workOrderStageModel;
    @Resource
    private WorkOrderBasicService workOrderBasicService;
    @Resource
    private WorkOrderCcModel workOrderCcModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private LabelHelp labelHelp;
    @Resource
    private WorkOrderFlowUserModel workOrderFlowUserModel;
    @Resource
    private LinkListService linkListService;
    @Resource
    private DetailTabConfigService detailTabConfigService;
    @Resource
    private FormDataDetailAnalysisDataHelp formDataDetailAnalysisDataHelp;

    @Override
    public List<Integer> businessType() {
        return Arrays.asList(XbbRefTypeEnum.WORK_ORDER.getCode());
    }


    @Override
    public WorkOrderFormEntityExt getForm(FormDataDetailDTO formDataDetailDTO, WorkOrderEntity form, String corpid) throws XbbException {
        WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(form.getFormId(), corpid);
        if ( Objects.isNull(workOrderFormEntityExt) ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(workOrderFormEntityExt.getTemplateId(), corpid);
        // 工单详情页模板权限校验，工单模板设置的可见范围
        UserVO loginUser = formDataDetailDTO.getLoginUser();
        String userId = loginUser.getUserId();
        if (!(loginUser.isAdminOrBoss() || loginUser.isMaxDataPermission())) {
            String scopeRule = workOrderTemplateEntity.getScopeRule();
            JSONObject scopeRuleObj =  JSONObject.parseObject(scopeRule);
            String deptStr = scopeRuleObj.getString("dept");
            List<Long> deptList = JSONArray.parseArray(deptStr, Long.class);
            String userStr = scopeRuleObj.getString("user");
            List<String> userList = JSONArray.parseArray(userStr, String.class);
            if (deptList != null && userList != null) {
                List<String> depUserIdList = new ArrayList<>();
                if (deptList.size() > 0) {
                    // 获取子部门的depId
                    deptList = departmentModel.getSubDepIdList(corpid, deptList);
                    depUserIdList = userModel.getDepUserIdList(corpid, deptList);
                }
                userList.addAll(depUserIdList);
                if (userList.size() > 0 && !userList.contains(userId)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100017);
                }
            }
        }
        return workOrderFormEntityExt;
    }

    @Override
    public List<ButtonPojo> handleDetailButton(FormDataDetailDTO formDataDetailDTO, HandelDetailPojo handelDetailPojo, WorkOrderEntity paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        UserEntity userEntity = new UserEntity();
        UserVO userVO = handelDetailPojo.getLoginUser();
        BeanUtil.copyProperties(userVO, userEntity);
        boolean isBoss = userVO.isAdminOrBoss();
        boolean isWorkOrderDispatcher = false;
        boolean isWorkOrderManager = false;
        boolean isCreator = Objects.equals(userEntity.getUserId(), paasFormDataEntityExt.getCreatorId());
        WorkOrderFlowUserEntity mainUser = workOrderFlowUserService.getMainUser(paasFormDataEntityExt.getId(), paasFormDataEntityExt.getCorpid());
        boolean isMain = false;
        if (Objects.nonNull(mainUser) && Objects.equals(mainUser.getUserId(), userVO.getUserId())) {
            isMain = true;
        }

        Set<RoleSimpleVO> roleSet = userVO.getRoleSet();
        Set<String> permSet = userVO.getPermSet();
//工单完成状态可编辑权限
        Boolean isWorkOrderFinishedEdit = ProPermissionHelp.hasThisPermission(userVO,ProPermissionAliasEnum.WORK_ORDER_FINISHED_EDIT.getAlias());
        for (RoleSimpleVO roleSimpleVO : roleSet) {
            if (Objects.equals(roleSimpleVO.getId(), RoleEnum.WORKORDER_DISPATCHER.getCode())) {
                isWorkOrderDispatcher = true;
            }
            if (Objects.equals(roleSimpleVO.getId(), RoleEnum.WORKORDER_MANAGER.getCode())) {
                isWorkOrderManager = true;
            }
        }
        List<BusinessDetailButtonEnum> buttonEnumList = BusinessDetailButtonEnum.getByBusinessTypeAndPermission(handelDetailPojo.getBusinessType(), userVO.getPermSet());
        Integer workOrderStatus = paasFormDataEntityExt.getStatus();
        List<ButtonPojo> buttonPojoList = new ArrayList<>();
        for (BusinessDetailButtonEnum buttonEnum : buttonEnumList) {
            if (Objects.equals(buttonEnum, BusinessDetailButtonEnum.WORK_ORDER_CENETR_DETAIL_EDIT)) {
                if (Objects.equals(workOrderStatus, WorkOrderStatusEnum.FINISH.getCode())) {
                    //工单"完成"状态，仅设置了工单完成状态可编辑权限情况下可编辑
                    if (!isWorkOrderFinishedEdit) {
                        continue;
                    }
                } else {
                    //	创建人，老板、超管等最高权限人员，主负责人，派单员，工单主管。其他角色可自定义添加此权限。
                    if (!(isCreator || isBoss || isMain || ((isWorkOrderDispatcher || isWorkOrderManager) || permSet.contains(UpdateProPermissionAliasEnum.WORK_ORDER_UPDATE.getAlias())))) {
                        continue;
                    }
                }
            }
            if (Objects.equals(buttonEnum, BusinessDetailButtonEnum.WORK_ORDER_CENETR_DETAIL_DEL)) {
                if (!(isCreator || isBoss || isMain || (isWorkOrderManager && permSet.contains(DeleteProPermissionAliasEnum.WORK_ORDER_DEL.getAlias())) || permSet.contains(DeleteProPermissionAliasEnum.WORK_ORDER_DEL.getAlias()))) {
                    continue;
                }
            }
            ButtonPojo buttonPojo = new ButtonPojo();
            SaasButtonEnum saasButtonEnum = buttonEnum.getAnEnum();
            BeanUtil.copyProperties(saasButtonEnum, buttonPojo);
            buttonPojo.setLinkBusinessType(buttonEnum.getLinkBusinessType());
            buttonPojoList.add(buttonPojo);
        }
        return buttonPojoList;
    }


    @Override
    public DetailTitlePojo handleDetailFocus(FormDataDetailDTO formDataDetailDTO, Integer businessType, WorkOrderEntity paasFormDataEntityExt, String userId) throws XbbException {
        return new DetailTitlePojo();
    }

    @Override
    public List<WorkFlowPojo> webHandleDetailWorkFlow(HandelDetailPojo handelDetailPojo, WorkOrderFormEntityExt formEntity, WorkOrderEntity paasFormDataEntityExt) throws XbbException {
        UserVO userVO = handelDetailPojo.getLoginUser();
        List<WorkFlowPojo> workFlowPojoList = getWorkFlow(handelDetailPojo, formEntity, paasFormDataEntityExt);
        List<LinkListPojo> linkList = JSON.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        workFlowPojoList.addAll(linkListService.getCommonButton(linkList, paasFormDataEntityExt.getDel(), userVO, paasFormDataEntityExt.getAppId(), paasFormDataEntityExt.getFormId(), XbbRefTypeEnum.WORK_ORDER.getCode(), SaasMarkEnum.SAAS.getCode(), paasFormDataEntityExt.getCorpid()));
        return workFlowPojoList;
    }

    /**
     * pc端关联新建，移动端关联操作
     * @param handelDetailPojo
     * @param formEntity
     * @param paasFormDataEntityExt
     * @return
     * @throws XbbException
     */

    private List<WorkFlowPojo> getWorkFlow(HandelDetailPojo handelDetailPojo, WorkOrderFormEntityExt formEntity, WorkOrderEntity paasFormDataEntityExt) throws XbbException {
        String corpid = formEntity.getCorpid();
        UserVO userVO = handelDetailPojo.getLoginUser();
        Long workOrderId = paasFormDataEntityExt.getId();
        WorkOrderEntity workOrderEntity = workOrderModel.getByKey(workOrderId, corpid);
        if (Objects.isNull(workOrderEntity) || Objects.equals(workOrderEntity.getDel(), DelEnum.DELETE.getDel())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        List<WorkOrderFlowNodeEntity> workOrderFlowNodeEntities = workOrderFlowNodeModel.getNode(workOrderId, 1, corpid);
        WorkOrderFlowNodeEntity workOrderFlowNodeEntity = workOrderFlowNodeEntities.get(0);
        WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(workOrderEntity.getTemplateId(), corpid);
        boolean isFirst = false;
        Long sourceId = workOrderFlowNodeEntity.getSourceId();
        Integer sort = workOrderFlowNodeEntity.getSort();
        //如果回退原id不等于0，即说明当前节点是回退后生成的，需要查找原节点位置
        if (sourceId != 0) {
            WorkOrderFlowNodeEntity sourceNode = workOrderFlowNodeModel.getByKey(sourceId, corpid);
            sort = sourceNode.getSort();
        }
        List<String> accepteUserIds = new ArrayList<>();
        if (workOrderTemplateEntity.getIsFree().equals(1)) {
            //自由流程
            isFirst = sort.equals(0);
            accepteUserIds.add(workOrderFlowNodeEntity.getUserId());
        } else {
            //指定流程
            WorkOrderStageEntity workOrderStageEntity = workOrderStageModel.getByKey(workOrderEntity.getNowStageId(), corpid);
            if (Objects.nonNull(workOrderStageEntity)) {
                isFirst = sort.equals(0) && workOrderStageEntity.getSort().equals(0);
                WorkOrderStageRuleEnum workOrderStageRuleEnum = WorkOrderStageRuleEnum.getByCode(workOrderStageEntity.getRuleId());
                WorkOrderStageRobTypeEnum workOrderStageRobTypeEnum = WorkOrderStageRobTypeEnum.getByCode(workOrderStageEntity.getRefRobType());
                switch (workOrderStageRuleEnum) {
                    case ROB:
                        switch (workOrderStageRobTypeEnum) {
                            case SERVICE:
                                accepteUserIds.addAll(workOrderBasicService.getServiceUserIdList(corpid, workOrderStageEntity.getRefRobId()));
                                break;
                            case DEPARTMENT:
                                accepteUserIds.addAll(workOrderBasicService.getDepartmentUserIdList(corpid, workOrderStageEntity.getRefRobId()));
                                break;
                            case USER:
                            default:
                                break;
                        }
                        break;
                    default:
                        accepteUserIds.add(workOrderFlowNodeEntity.getUserId());
                        break;
                }
            }
        }
        Integer nodeStatus = workOrderFlowNodeEntity.getStatus();
        WorkOrderNodeStatusEnum workOrderNodeStatusEnum = WorkOrderNodeStatusEnum.getByCode(nodeStatus);

        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(userVO, userEntity);
        //老板、超管等最高权限人员
        boolean isBoss = userVO.isAdminOrBoss();

        Set<RoleSimpleVO> roleSet = userVO.getRoleSet();

        //工单主管
        boolean isWorkOrderManager = false;
        for (RoleSimpleVO roleSimpleVO : roleSet) {
            if (Objects.equals(roleSimpleVO.getId(), RoleEnum.WORKORDER_MANAGER.getCode())) {
                isWorkOrderManager = true;
                break;
            }
        }
        //负责人
        boolean isMain = false;
        //协同人
        boolean isCoop = false;
        //抄送人
        boolean isCc = false;
        //创建人
        boolean isCreator = Objects.equals(userEntity.getUserId(), workOrderEntity.getCreatorId());

        List<WorkOrderFlowUserEntity> teamUserList = workOrderFlowUserService.getTeamUserList(workOrderId, corpid);
        for (WorkOrderFlowUserEntity flowUserEntity : teamUserList) {
            if (Objects.equals(flowUserEntity.getUserId(), userEntity.getUserId())) {
                if (Objects.equals(flowUserEntity.getIsMain(), 1)) {
                    isMain = true;
                }
                if (Objects.equals(flowUserEntity.getIsMain(), 0)) {
                    isCoop = true;
                }
                break;
            }
        }
        List<String> ccUserIds = workOrderCcModel.getUserIds(corpid, workOrderId);
        if (ccUserIds.contains(userVO.getUserId())) {
            isCc = true;
        }

        //根据工单节点状态赋默认全部操作权限
        LinkedList<WorkFlowEnum> workFlowEnums = new LinkedList<>();
        List<WorkFlowEnum> workFlowEnumList = WorkFlowEnum.getByBusinessTypeAndPermission(handelDetailPojo.getBusinessType(), userVO.getPermSet());
        for (WorkFlowEnum workFlowEnum : workFlowEnumList) {
            switch (workOrderNodeStatusEnum) {
                case UNACCEPTED:
                case TRANSFERRED:
                    if (workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_TRANSFER) || workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_COMPLETE) || workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_RESTART) || workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_ROLLBACK)) {
                        continue;
                    }
                    break;
                case ROLLBACK:
                case RESTART:
                case ONGOING:
                    if (workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_ACCEPTED) || workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_RESTART)) {
                        continue;
                    }
                    if (workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_ROLLBACK)) {
                        if (isFirst) {
                            continue;
                        }
                    }
                    break;
                case FINISH:
                case CLOSE:
                    if (workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_ACCEPTED) || workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_TRANSFER) || workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_COMPLETE) || workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_CLOSE) || workFlowEnum.equals(WorkFlowEnum.WORK_ORDER_ROLLBACK)) {
                        continue;
                    }
                    break;
                case UNKNOWN:
                default:
                    break;
            }
            workFlowEnums.add(workFlowEnum);
        }
        if (isCc && !(isMain || isBoss || isWorkOrderManager || accepteUserIds.contains(userVO.getUserId()))) {
            //抄送人只能看，所有流转操作都没
            workFlowEnums.removeAll(Arrays.asList(WorkFlowEnum.WORK_ORDER_ACCEPTED, WorkFlowEnum.WORK_ORDER_COMPLETE, WorkFlowEnum.WORK_ORDER_TRANSFER, WorkFlowEnum.WORK_ORDER_CLOSE, WorkFlowEnum.WORK_ORDER_RESTART, WorkFlowEnum.WORK_ORDER_ROLLBACK));
        } else {
            //根据权限移除无权限的按钮
            //接收,完成,转派,  工单负责人、老板、超管等最高权限人员，工单主管。
            //接收还有抢单的人
            if (!StringUtil.isEmpty(workOrderFlowNodeEntity.getUserId())) {
                if (!(isBoss || isWorkOrderManager)) {
                    if (!Objects.equals(workOrderFlowNodeEntity.getUserId(), userVO.getUserId())) {
                        workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_ACCEPTED);
                    }
                }
            } else {
                if (Objects.equals(workOrderFlowNodeEntity.getNodeType(), WorkOrderFlowNodeTypeEnum.ROB_NODE.getCode())) {
                    if (!(isBoss || isWorkOrderManager || accepteUserIds.contains(userVO.getUserId()))) {
                        workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_ACCEPTED);
                    }
                } else {
                    if (!(isMain || isBoss || isWorkOrderManager || accepteUserIds.contains(userVO.getUserId()))) {
                        workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_ACCEPTED);
                    }
                }
            }
            if (!(isMain || isBoss || isWorkOrderManager)) {
                workFlowEnums.removeAll(Arrays.asList(WorkFlowEnum.WORK_ORDER_COMPLETE, WorkFlowEnum.WORK_ORDER_TRANSFER));
            }
            // 关闭, 非协同人（只要不是协同人，都可以），老板、超管等最高权限人员，工单主管。
            //抢单工单-关闭  	 主负责人，老板、超管等最高权限人员，工单主管。
            if (Objects.equals(workOrderEntity.getType(), WorkOrderTypeEnum.ROB.getCode())) {
                if (!(isMain || isBoss || isWorkOrderManager)) {
                    workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_CLOSE);
                }
            } else {
                if (isCoop && !isBoss && !isWorkOrderManager) {
                    workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_CLOSE);
                } else if (isCc && !isMain && !isBoss && !isWorkOrderManager) {
                    workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_CLOSE);
                } else if (!(isMain || isCoop || isBoss || isWorkOrderManager)) {
                    workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_CLOSE);
                }
            }
            // 重启,	创建人，老板、超管等最高权限人员，工单主管。
            if (!(isCreator || isBoss || isWorkOrderManager)) {
                workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_RESTART);
            }
            // 回退, 	 主负责人，老板、超管等最高权限人员，工单主管。
            if (!(isMain || isBoss || isWorkOrderManager)) {
                workFlowEnums.remove(WorkFlowEnum.WORK_ORDER_ROLLBACK);
            }
        }
        // 获取对应businessType的alias
        List<String> aliasIn = WorkFlowEnum.getAliasIn(workFlowEnumList);
        // 记录businessType与menuName的关系
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, handelDetailPojo.getBusinessType());

        // 过滤掉全部出库和无关联产品的情况
        Integer shippedFlag = getIntegerOrDefaultFromFormData(paasFormDataEntityExt.getData(), WorkOrderEnum.SHIP_STATUS.getAttr(), WorkOrderShipStatusEnum.EMPTY.getCode());
        List<WorkFlowPojo> workFlowPojoList = new ArrayList<>();
        for (WorkFlowEnum workFlowEnum : workFlowEnums) {
            if ((Objects.equals(shippedFlag, WorkOrderShipStatusEnum.SHIPPED.getCode()) || Objects.equals(shippedFlag, WorkOrderShipStatusEnum.EMPTY.getCode())) && Objects.equals(workFlowEnum, WorkFlowEnum.WORK_ORDER_OUTSTOCK)) {
                continue;
            }
            WorkFlowPojo workFlowPojo = new WorkFlowPojo();
            BeanUtil.copyProperties(workFlowEnum, workFlowPojo);
            NameUtil.changeValue(paasBusinessTypeToName, workFlowPojo);
            workFlowPojoList.add(workFlowPojo);
        }
        return workFlowPojoList;
    }


    @Override
    public List<TopPermissionsPoJo> dingtalkHandleDetailWorkFlow(HandelDetailPojo handelDetailPojo, WorkOrderFormEntityExt formEntity, WorkOrderEntity paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        UserEntity userEntity = new UserEntity();
        UserVO loginUser = handelDetailPojo.getLoginUser();
        Set<String> loginUserPermSet = loginUser.getPermSet();
        Set<RoleSimpleVO> loginUserRoleSet = loginUser.getRoleSet();
        BeanUtil.copyProperties(loginUser, userEntity);
        boolean isBoss = loginUser.isAdminOrBoss();
        boolean isCreator = Objects.equals(paasFormDataEntityExt.getCreatorId(), userEntity.getUserId());
        WorkOrderFlowUserEntity mainUser = workOrderFlowUserService.getMainUser(paasFormDataEntityExt.getId(), paasFormDataEntityExt.getCorpid());
        boolean isMain = false;
        if (Objects.nonNull(mainUser) && Objects.equals(mainUser.getUserId(), loginUser.getUserId())) {
            isMain = true;
        }
        boolean isWorkOrderDispatcher = false;
        boolean isWorkOrderManager = false;
        for (RoleSimpleVO roleSimpleVO : loginUserRoleSet) {
            if (Objects.equals(roleSimpleVO.getId(), RoleEnum.WORKORDER_DISPATCHER.getCode())) {
                isWorkOrderDispatcher = true;
            }
            if (Objects.equals(roleSimpleVO.getId(), RoleEnum.WORKORDER_MANAGER.getCode())) {
                isWorkOrderManager = true;
            }
        }
        List<String> aliasIn = new ArrayList<>();
        List<WorkFlowEnum> workFlowEnumList = WorkFlowEnum.getByBusinessTypeAndPermissionForDingtalk(handelDetailPojo.getBusinessType(), loginUser.getPermSet());
        workFlowEnumList.forEach(item -> aliasIn.add(XbbRefTypeEnum.getByCode(item.getBusinessType()).getAlias()));
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, formEntity.getCorpid(), handelDetailPojo.getBusinessType());

        //工单完成状态可编辑权限
        Boolean isWorkOrderFinishedEdit = ProPermissionHelp.hasThisPermission(loginUser,ProPermissionAliasEnum.WORK_ORDER_FINISHED_EDIT.getAlias());

        JSONObject dataList = paasFormDataEntityExt.getData();
        List<TopPermissionsPoJo> topPermissions = new ArrayList<>();
        Integer shippedFlag = getIntegerOrDefaultFromFormData(dataList, WorkOrderEnum.SHIP_STATUS.getAttr(), WorkOrderShipStatusEnum.EMPTY.getCode());
        for (WorkFlowEnum workFlowEnum : workFlowEnumList) {
            if (Objects.equals(workFlowEnum, WorkFlowEnum.WORK_ORDER_DETAIL_EDIT)) {
//编辑权限
                if (Objects.equals(paasFormDataEntityExt.getStatus(), WorkOrderStatusEnum.FINISH.getCode())) {
                    //工单"完成"状态，仅设置了工单完成状态可编辑权限情况下可编辑
                    if (!isWorkOrderFinishedEdit) {
                        continue;
                    }
                } else {
                    //	创建人，老板、超管等最高权限人员，主负责人，派单员，工单主管。其他角色可自定义添加此权限。
                    if (!(isCreator || isBoss || isMain || ((isWorkOrderDispatcher || isWorkOrderManager) || loginUserPermSet.contains(UpdateProPermissionAliasEnum.WORK_ORDER_UPDATE.getAlias())))) {
                        continue;
                    }
                }
            }
            if (Objects.equals(workFlowEnum, WorkFlowEnum.WORK_ORDER_DETAIL_DEL)) {
                if (!(isCreator || isBoss || isMain || (isWorkOrderManager && loginUserPermSet.contains(DeleteProPermissionAliasEnum.WORK_ORDER_DEL.getAlias())) || loginUserPermSet.contains(DeleteProPermissionAliasEnum.WORK_ORDER_DEL.getAlias()))) {
                    continue;
                }
            }
            // 过滤掉全部出库和无关联产品的情况
            if ((Objects.equals(shippedFlag, WorkOrderShipStatusEnum.SHIPPED.getCode()) || Objects.equals(shippedFlag, WorkOrderShipStatusEnum.EMPTY.getCode()))
                    && Objects.equals(workFlowEnum, WorkFlowEnum.WORK_ORDER_OUTSTOCK)) {
                continue;
            }
            TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
            BeanUtil.copyProperties(workFlowEnum, topPermissionsPoJo);
            if (Objects.equals(workFlowEnum.getFormRelation(), BasicConstant.ONE)) {
                NameUtil.changeValue(paasBusinessTypeToName, topPermissionsPoJo);
            }
            topPermissions.add(topPermissionsPoJo);
        }
        List<LinkListPojo> linkList = JSON.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        topPermissions.addAll(linkListService.getDingtalkCommonButton(linkList, paasFormDataEntityExt.getDel(), loginUser, paasFormDataEntityExt.getAppId(), paasFormDataEntityExt.getFormId(), XbbRefTypeEnum.WORK_ORDER.getCode(), SaasMarkEnum.SAAS.getCode(), paasFormDataEntityExt.getCorpid()));
        return topPermissions;
    }

    @Override
    public DataDetailPojo handleDetailData(Integer businessType, WorkOrderEntity formData, String userId, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        // 外链
        DataDetailPojo dataDetailPojo = new DataDetailPojo();
        Integer outerLinkShare = setOuterLinkShare(handlerExplainDTO.getCorpid(), formData.getFormId());
        dataDetailPojo.setHasOuterLinkShare(outerLinkShare);
        return dataDetailPojo;
    }

    @Override
    public void handleDetailSpecialField(WorkOrderEntity formData, JSONObject data, Map<String, FieldAttrEntity> explainMap, HandlerExplainDTO handlerExplainDTO) throws XbbException {

    }

    @Override
    public List<SummaryDataPoJo> getSummaryList(FormDataDetailDTO formDataDetailDTO, WorkOrderEntity formData, WorkOrderFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(formEntity.getTemplateId(), corpid);

        List<SummaryDataPoJo> summaryList = ExplainUtil.getSpecialSummaryList(formEntity.getSummaryList(), data, explainMap, formData);
// 移动端SaaS详情页额外展示信息
        if ( !Objects.equals(workOrderTemplateEntity.getIsFree(), 1) ) {
            //指定流程才有阶段
            SummaryDataPoJo summary = new SummaryDataPoJo();
            if (!Objects.equals(formData.getNowStageId(), 0L)) {
                WorkOrderStageEntity workOrderStageEntity = workOrderStageModel.getByKey(formData.getNowStageId(), formData.getCorpid());
                summary.setValue(Collections.singletonList(workOrderStageEntity.getName()));
                summary.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.STAGE_NAME));
                summaryList.add(summary);
            }
        }
        // 改动于com/xbongbong/saas/service/impl/MobileDetailServiceImpl.java:1420
        SummaryDataPoJo workOrderSummary = SummaryUtil.getSummaryDataPoJoByAttr(summaryList, WorkOrderEnum.ADDRESS.getAttr());
        if (Objects.nonNull(workOrderSummary)) {
            List<Object> values = workOrderSummary.getValue();
            if (Objects.nonNull(values) && !values.isEmpty()) {
                workOrderSummary.setValue(values);
            }
            JSONObject address = data.getJSONObject(WorkOrderEnum.ADDRESS.getAttr());
            if (Objects.nonNull(address) && Objects.nonNull(address.getJSONObject(LocationConstant.LOCATION))) {
                JSONObject location = address.getJSONObject(LocationConstant.LOCATION);
                Double latitude = getDoubleOrDefaultFromFormData(location, LocationConstant.LON, 0D);
                Double longitude = getDoubleOrDefaultFromFormData(location, LocationConstant.LAT, 0D);
                workOrderSummary.setAddressExtra(latitude, longitude);
            }
        }
        //自由流程不限时工单
        boolean isLimit = Objects.equals(workOrderTemplateEntity.getIsFree(), 1) && Objects.equals(workOrderTemplateEntity.getExpectedTime(), 0);
        WorkOrderFlowNodeEntity workOrderFlowNodeEntity = workOrderFlowNodeModel.getNode(formData.getId(), 1, corpid).get(0);
        SummaryDataPoJo summary1 = new SummaryDataPoJo();
        if ( isLimit ) {
            summary1.setValue(Collections.singletonList(""));
        } else {
            summary1.setValue(Collections.singletonList(workOrderBasicService.workOrderNodeConsueTime(workOrderFlowNodeEntity).getConsumeTimeStr()));
        }
        summary1.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.STAGE_TIME_CONSUMING));
        summaryList.add(summary1);

        WorkOrderEntityExt workOrderEntityExt = new WorkOrderEntityExt();
        BeanUtil.copyProperties(formData, workOrderEntityExt);
        SummaryDataPoJo summary2 = new SummaryDataPoJo();
        if ( isLimit ) {
            summary2.setValue(Collections.singletonList(workOrderBasicService.workOrderSpecialConsueTime(workOrderEntityExt).getConsumeTimeStr()));
        } else {
            summary2.setValue(Collections.singletonList(workOrderBasicService.workOrderConsueTime(workOrderEntityExt).getConsumeTimeStr()));
        }
        summary2.setAttrName(I18nMessageUtil.getMessage(I18nStringConstant.WORKORDER_TIME_CONSUMING));
        summaryList.add(summary2);
        return summaryList;
    }

    @Override
    public JSONArray getSecondTitleList(FormDataDetailDTO formDataDetailDTO, WorkOrderEntity formData, WorkOrderFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        List<SummaryDataPoJo> summaryList = ExplainUtil.getSpecialSummaryList(formEntity.getSummaryList(), data, explainMap, formData);
        return getSecondTitleList(summaryList, data, formDataDetailDTO.getCorpid(), formEntity.getId());
    }

    @Override
    public JSONArray getTagList(FormDataDetailDTO formDataDetailDTO, WorkOrderEntity formData, WorkOrderFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        String corpid = formDataDetailDTO.getCorpid();
        Integer businessType = XbbRefTypeEnum.WORK_ORDER.getCode();
        Long dataId = formData.getId();
        String userId = formDataDetailDTO.getUserId();
        // 获取标签
        List<SummaryDataPoJo> labelsList = getLabelList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        JSONArray tags = getTags(labelsList, corpid, businessType, dataId, userId);
        return tags;
    }


    @Override
    public List<SummaryDataPoJo> getLabelList(FormDataDetailDTO formDataDetailDTO, WorkOrderEntity formData, WorkOrderFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {

        // 解析标签
        List<SummaryDataPoJo> labelsList = ExplainUtil.getSpecialSummaryList(formEntity.getLabelsList(), data, explainMap, formData);
        WorkOrderSummaryServiceImpl workOrderSummaryService = new WorkOrderSummaryServiceImpl();
        workOrderSummaryService.handleSummarySpecialAttr(formDataDetailDTO.getCorpid(), labelsList, XbbRefTypeEnum.WORK_ORDER.getCode(), data, formData.getId(), formData);

        return labelsList;
    }

    @Override
    public List<FormTitlePoJo> getTitleList(FormDataDetailDTO formDataDetailDTO, WorkOrderEntity formData, WorkOrderFormEntityExt formEntity, List<FieldAttrEntity> explainList, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {

        List<FormTitlePoJo> formTitleList = ExplainUtil.getSpecailFormTitle(JSONArray.parseArray(formEntity.getCustomTitle()), explainMap, data, explainList, formData);

        return formTitleList;
    }

    @Override
    public String getTitle(FormDataDetailDTO formDataDetailDTO, WorkOrderEntity formData, WorkOrderFormEntityExt formEntity, List<FieldAttrEntity> list, Map<String, FieldAttrEntity> explainMap, JSONObject data) throws XbbException {
        List<FormTitlePoJo> formTitleList = getTitleList(formDataDetailDTO, formData, formEntity, list, explainMap, data);
        return TitleUtil.getWebTitle(formTitleList);
    }


    @Override
    public List<DetailTabPojo> handleDetailTab(HandelDetailPojo handelDetailPojo, WorkOrderFormEntityExt formEntity, WorkOrderEntity formData, Map<String, FieldAttrEntity> explainMap, HandlerExplainVO handlerExplainVO, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        // 判断电话字段是否可见
        boolean workOrderMobile = commonHelp.attrCanSee(WorkOrderEnum.CONTACT_INFORMATION.getAttr(), explainMap, handlerExplainDTO);
        if(workOrderMobile){
            List<? extends FieldAttrEntity> explainSubFormList = explainMap.get(WorkOrderEnum.CONTACT_INFORMATION.getAttr()).getSubForm().getItems();
            Map<String, FieldAttrEntity> explainSubFormMap = new HashMap<>(explainSubFormList.size());
            explainSubFormList.forEach((item) -> explainSubFormMap.put(item.getAttr(), item));
            boolean text2CanSee = commonHelp.attrCanSee(StringConstant.PHONE_TEL_ATTR, explainSubFormMap, handlerExplainDTO);
            if(!text2CanSee){
                workOrderMobile = false;
            }
        }

        UserVO userVO = handelDetailPojo.getLoginUser();
        Integer businessType = handelDetailPojo.getBusinessType();
        String corpid = handlerExplainDTO.getCorpid();
        List<BusinessDetailTabEnum> tabEnumList =  BusinessDetailTabEnum.getTabByBusinessTypeAndPermission(businessType, userVO.getPermSet(), handlerExplainDTO.getPlatform());
        // 判断应用是否启用
        boolean isSmsUse = paasAppModel.validateAppEnable(null, XbbRefTypeEnum.GROUP_MESSAGE.getAlias(), 1, corpid);
        // 判断当前员工有没有短信权限
        boolean canSms = isSmsUse && userVO.getPermSet().contains(ProPermissionAliasEnum.SMS_VIEW.getAlias());
// 获取对应businessType的alias
        List<String> aliasIn = BusinessDetailTabEnum.getAliasIn(tabEnumList);

        // 记录businessType与menuName的关系
        Map<Integer, String> paasBusinessTypeToName = paasMenuModel.getMenuNameByAlias(aliasIn, corpid, businessType);
        List<DetailTabPojo> tabPojoList = new ArrayList<>();
        for (BusinessDetailTabEnum tabEnum : tabEnumList) {
            if (!canSms && Objects.equals(tabEnum, BusinessDetailTabEnum.WORK_ORDER_SMS_SEND_AND_REPLY)) {
                continue;
            }
            // 短信往来tab
            if (!workOrderMobile && Objects.equals(tabEnum, BusinessDetailTabEnum.WORK_ORDER_SMS_SEND_AND_REPLY)) {
                continue;
            }
            DetailTabPojo detailTabPojo = new DetailTabPojo();
            BeanUtil.copyProperties(tabEnum.getAnEnum(), detailTabPojo);
            NameUtil.changeTabEnumName(paasBusinessTypeToName, tabEnum, detailTabPojo);
            detailTabPojo.setAttr(detailTabPojo.getKey());
            tabPojoList.add(detailTabPojo);
        }
        handleTeamTab(tabPojoList, explainMap);
        List<LinkListPojo> linkList = JSONArray.parseArray(formEntity.getAssociationList(), LinkListPojo.class);
        handlerExplainVO.setAppId(formEntity.getAppId());
        handlerExplainVO.setFormId(formEntity.getId());
        // 公共tab
        tabPojoList.addAll(linkListService.commonTab(corpid, userVO, handlerExplainVO, handlerExplainDTO, businessType, formData.getDel(), linkList));
        // tab排序
        tabPojoList = detailTabConfigService.handleDetailTabSort(userVO.getUserId(), corpid, handlerExplainVO.getFormId(), businessType, tabPojoList);

        return tabPojoList;
    }

    @Override
    public String dealWebDetailLabelListLocation(FormDataDetailDTO formDataDetailDTO, WorkOrderFormEntityExt formEntity, JSONArray tags, WorkOrderEntity paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        JSONArray labelList = JSONArray.parseArray(formEntity.getLabels());
        return labelHelp.dealWebDetailLabelListLocation(formDataDetailDTO, labelList,tags, paasFormDataEntityExt, explainMap);
    }

    @Override
    public WorkOrderEntity getData(Integer businessType, Integer subBusinessType, Integer saasMark, String corpid, Long dataId, Long formId) throws XbbException {
        WorkOrderEntity workOrderEntity = workOrderModel.getByKey(dataId, corpid);
        if ( Objects.isNull(workOrderEntity) || Objects.equals(workOrderEntity.getDel(), DelEnum.DELETE.getDel()) ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        //审批中数据不让看，直接报错，目前这样处理，后续优化为可见，但没有任何操作权限
        if ( FlowStatusEnum.inApproval(workOrderEntity.getFlowStatus()) ) {
            throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200023);
        }
        return workOrderEntity;
    }

    @Override
    public void checkPermission(WorkOrderFormEntityExt formEntity, WorkOrderEntity paasFormDataEntityExt, UserVO loginUser, Integer businessType) throws XbbException {
// 查看权限校验
        VerifyViewPermissionDTO verifyViewPermissionDTO = new VerifyViewPermissionDTO();
        verifyViewPermissionDTO.setLoginUser(loginUser);
        verifyViewPermissionDTO.setMenuId(paasFormDataEntityExt.getMenuId());
        verifyViewPermissionDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        verifyViewPermissionDTO.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
        ProPermissionHelp.verifyQueryPermission(verifyViewPermissionDTO);

    }

    @Override
    public List<FieldAttrEntity> getExplainList(WorkOrderFormEntityExt form, String corpid) throws XbbException {
        WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(form.getId(), corpid);
        if ( Objects.isNull(workOrderExplainEntity) ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        return JSONArray.parseArray(workOrderExplainEntity.getExplains(), FieldAttrEntity.class);
    }

    @Override
    public HandlerExplainVO handleExplain(List<FieldAttrEntity> explainList, WorkOrderFormEntityExt formEntity, WorkOrderEntity workOrderEntity, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        handlerExplainDTO.setExplainList(explainList);
        ownerAndCoUserHelp.getOwnerIdAndCoUserId(handlerExplainDTO, handlerExplainDTO.getSaasMark(), handlerExplainDTO.getBusinessType(), workOrderEntity, new HashMap<>(), DelEnum.NORMAL.getDel());
        return workOrderFormDataFormExplainHandleName.handlerExplain(handlerExplainDTO, explainList, formEntity, workOrderEntity);
    }

    @Override
    public JSONObject analysisData(WorkOrderEntity formData, HandlerExplainDTO handlerExplainDTO, HandlerExplainVO handlerExplainVO) throws XbbException {
        List<FieldAttrEntity> list = handlerExplainVO.getHeadList();
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(list.size());
        list.forEach(item->explainMap.put(item.getAttr(), item));

        PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt(formData.getId(), formData.getCorpid(), formData.getAppId(), formData.getMenuId(), formData.getFormId(), formData.getSerialNo(), formData.getOwnerId(), formData.getDepartmentId(), formData.getFlowStatus(), formData.getData(), formData.getCreatorId(), formData.getAddTime(), formData.getUpdateTime(), formData.getDel());


        ParseSingleRowDataVO parseSingleRowDataVO = commonAnalysisData(paasFormDataEntityExt, handlerExplainDTO, handlerExplainVO, list, explainMap);
        JSONObject data = parseSingleRowDataVO.getResult();
        SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();

        workOrderModel.formatData(saasAnalysisDataDTO, data);
        return data;
    }


    @Override
    public List<MobileDetailMoneyItemPojo> getMobileDetailMoneyInfo(Integer distributorMark, String corpid, String userId, Integer businessType, Integer subBusinessType, Long dataId, JSONObject data, Map<String, FieldAttrEntity> explainMap, UserVO loginUser, WorkOrderEntity workOrderEntity) throws XbbException {
        return new ArrayList<>();
    }

    @Override
    public JSONArray getBottomBlockInfo(String corpid, String userId, Integer businessType, WorkOrderFormEntityExt workOrderFormEntityExt, Long dataId, JSONObject data, Map<String, FieldAttrEntity> explainMap, WorkOrderEntity entityExt, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid",corpid);
        param.put("del",0);
        param.put("workOrderId",dataId);
        List<WorkOrderFlowUserEntity> workOrderFlowUserEntityList = workOrderFlowUserModel.findEntitys(param);
        List<String> userIdIn = new ArrayList<>();
        workOrderFlowUserEntityList.forEach(item -> userIdIn.add(item.getUserId()));
        Map<String, UserEntity> userMap = new HashMap<>(userIdIn.size());
        List<UserEntity> userEntityList = userModel.getByUserIdIn(corpid, userIdIn, true);
        userEntityList.forEach(item -> userMap.put(item.getUserId(), item));
        List<CustomerUserPojo> userPojoList = new ArrayList<>();
        workOrderFlowUserEntityList.forEach(item -> {
            UserEntity userEntity = userMap.get(item.getUserId());
            if (userEntity != null) {
                CustomerUserPojo workOrderUserPojo = new CustomerUserPojo();
                workOrderUserPojo.setUserId(userEntity.getUserId());
                workOrderUserPojo.setName(userEntity.getName());
                workOrderUserPojo.setAvatar(userEntity.getAvatar());
                workOrderUserPojo.setIsMain(item.getIsMain());
                userPojoList.add(workOrderUserPojo);
            }
        });
        JSONArray bottomBlockInfo = new JSONArray();
        bottomBlockInfo.add(new MobileDetailManagerBlockPojo(userPojoList));
        HandelDetailPojo handelDetailPojo = new HandelDetailPojo(DistributorMarkEnum.OTHER.getCode(), businessType, null, new ArrayList<>(), handlerExplainDTO.getLoginUser());
        List<WorkFlowPojo> workFlowPojoList = getWorkFlow(handelDetailPojo, workOrderFormEntityExt, entityExt);
        List<ItemPoJo> itemPoJoList = new ArrayList<>();
        for ( WorkFlowPojo pojo : workFlowPojoList ) {
            ItemPoJo itemPoJo = new ItemPoJo();
            itemPoJo.setText(pojo.getValue());
            itemPoJo.setValue(pojo.getAttr());
            itemPoJoList.add(itemPoJo);
        }
        MobileDetailStatusBlockPojo statusBlockPojo = new MobileDetailStatusBlockPojo();
        statusBlockPojo.setOptions(itemPoJoList);
        bottomBlockInfo.add(statusBlockPojo);
        return bottomBlockInfo;
    }

    @Override
    public MobileDetailSpecialInfoPojo getMobileDetailSpecialInfo(FormDataDetailDTO formDataDetailDTO, WorkOrderEntity paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        JSONObject data = paasFormDataEntityExt.getData();
        Integer businessType = formDataDetailDTO.getBusinessType();
        String corpid = formDataDetailDTO.getCorpid();
        UserVO loginUser = formDataDetailDTO.getLoginUser();
        String userId = formDataDetailDTO.getUserId();
        Long dataId = paasFormDataEntityExt.getId();
        List<MobileDetailScriptPojo> scriptPojoList = getDetailShowScript(businessType, loginUser,paasFormDataEntityExt, explainMap);
        MobileDetailStatusPojo mobileDetailStatusPojo = getDetailShowStatus(businessType, data);
        Map<String, Object> operationList = getDetailShowOperation(corpid, userId, businessType, dataId, data);

        MobileDetailSpecialInfoPojo mobileDetailSpecialInfoPojo = new MobileDetailSpecialInfoPojo();
        mobileDetailSpecialInfoPojo.setScript(scriptPojoList);
        mobileDetailSpecialInfoPojo.setStatus(mobileDetailStatusPojo);
        mobileDetailSpecialInfoPojo.setOperation(operationList);
        return mobileDetailSpecialInfoPojo;
    }

    @Override
    public List<MobileDetailScriptPojo> getDetailShowScript(Integer businessType, UserVO loginUser, WorkOrderEntity paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        return new ArrayList<>();
    }

    @Override
    public MobileDetailStatusPojo getDetailShowStatus(Integer businessType, JSONObject data) throws XbbException {
        return new MobileDetailStatusPojo();
    }

    @Override
    public Map<String, Object> getDetailShowOperation(String corpid, String userId, Integer businessType, Long dataId, JSONObject data) throws XbbException {
        return new HashMap<>(BasicConstant.ONE);
    }

    @Override
    public JSONObject returnSaasObject(String corpid, Integer businessType, UserVO userVO, WorkOrderEntity paasFormDataEntityExt) throws XbbException {
        return new JSONObject();
    }

    @Override
    public List<TopPermissionsPoJo> getMobileDetailBottomOperation(HandelDetailPojo handelDetailPojo, WorkOrderFormEntityExt formEntity, WorkOrderEntity paasFormDataEntityExt, HandlerExplainDTO handlerExplainDTO, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        JSONArray phoneAttr = FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(), WorkOrderEnum.CONTACT_INFORMATION.getAttr(), new JSONArray());
        List<TopPermissionsPoJo> bottomOperationList = new ArrayList<>();
        Integer businessType = handelDetailPojo.getBusinessType();
        Integer businessType4Distributor = XbbRefTypeEnum.transferBusinessType4Distributor(businessType, handelDetailPojo.getDistributorMark());
        UserVO userVO = handelDetailPojo.getLoginUser();
        List<MobileDetailBottomOperationEnum> bottomOperationEnumList = MobileDetailBottomOperationEnum.getByBusinessTypeAndPermission(businessType4Distributor, userVO.getPermSet());
        if (phoneAttr.isEmpty()) {
            bottomOperationEnumList.remove(MobileDetailBottomOperationEnum.WORK_ORDER_CONTACT);
        }
        List<WorkFlowPojo> workFlowPojoList = webHandleDetailWorkFlow(handelDetailPojo, formEntity, paasFormDataEntityExt);

        for (MobileDetailBottomOperationEnum anEnum : bottomOperationEnumList) {
            TopPermissionsPoJo topPermissionsPoJo = new TopPermissionsPoJo();
            if (CollectionUtils.isEmpty(workFlowPojoList) && Objects.equals(anEnum, MobileDetailBottomOperationEnum.WORK_ORDER_OPERATION)) {
                continue;
            }
            BeanUtil.copyProperties(anEnum, topPermissionsPoJo);
            bottomOperationList.add(topPermissionsPoJo);
        }

        // 没有地址字段或者没有编辑权限的没有编辑按钮
        FieldAttrEntity fieldAttrEntity = explainMap.get(WorkOrderEnum.ADDRESS.getAttr());
        if (Objects.nonNull(fieldAttrEntity) && Objects.equals(fieldAttrEntity.getIsOpen(), BasicConstant.ONE)) {
            Boolean editableOfScope = ExplainUtil.isEditableOfScope(fieldAttrEntity, handlerExplainDTO);
            if (!editableOfScope) {
                bottomOperationList = bottomOperationList.stream().filter(v -> !Objects.equals(v.getAttr(), MobileDetailBottomOperationEnum.WORK_ORDER_LOCATION.getAttr())).collect(Collectors.toList());
            }
        } else {
            bottomOperationList = bottomOperationList.stream().filter(v -> !Objects.equals(v.getAttr(), MobileDetailBottomOperationEnum.WORK_ORDER_LOCATION.getAttr())).collect(Collectors.toList());
        }
        return bottomOperationList;
    }

    @Override
    public String dealAppDetailLabelListLocation(FormDataDetailDTO formDataDetailDTO, WorkOrderFormEntityExt formEntity, List<SummaryDataPoJo> labelList, WorkOrderEntity paasFormDataEntityExt, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        return labelHelp.dealAppDetailLabelListLocation(formDataDetailDTO, labelList, paasFormDataEntityExt, explainMap);
    }

    @Override
    public void returnVO(WorkOrderFormEntityExt formEntity, WorkOrderEntity formData, MobileFormCommonDetailVO mobileFormCommonDetailVO, String userId) throws XbbException {
        //工单状态
        WorkOrderStatusEnum workOrderStatusEnum = WorkOrderStatusEnum.getByCode(formData.getStatus());
        mobileFormCommonDetailVO.setWorkOrderStatus(workOrderStatusEnum.getName());
        Integer outerLinkShare = setOuterLinkShare(formEntity.getCorpid(), formEntity.getId());
        mobileFormCommonDetailVO.setHasOuterLinkShare(outerLinkShare);
        PaasFormEntity paasFormEntity = new PaasFormEntity();
        BeanUtil.copyProperties(formEntity, paasFormEntity);
        paasFormEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
        paasFormEntity.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
        mobileFormCommonDetailVO.setPaasFormEntity(paasFormEntity);
    }

    @Override
    public void analysisGetOfThousandBits(JSONObject data, List<FieldAttrEntity> explainList, Boolean analysisAmountOfThousandBitsWithOriginalValue) throws XbbException {
        formDataDetailAnalysisDataHelp.analysisGetOfThousandBits(data, explainList, analysisAmountOfThousandBitsWithOriginalValue);
    }
}
